Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split non macro portion of unused_doc_comment from macro part into two passes/lints #69084

Merged
merged 7 commits into from
Feb 23, 2020

Conversation

yaahc
Copy link
Member

@yaahc yaahc commented Feb 12, 2020

Motivation

This change is motivated by the needs of the spandoc library. The specific use case is that my macro is removing doc comments when an attribute is applied to a fn with doc comments, but I would like the lint to still appear when I forget to add the #[spandoc] attribute to a fn, so I don't want to have to silence the lint globally.

Approach

This change splits the unused _doc_comment lint into two lints, unused_macro_doc_comment and unused_doc_comment. The non macro portion is moved into an early_lint_pass rather than a pre_expansion_pass. This allows proc macros to silence unused_doc_comment warnings by either adding an attribute to silence it or by removing the doc comment before the early_pass runs.

The unused_macro_doc_comment lint however will still be impossible for proc-macros to silence, but the only alternative that I can see is to remove this lint entirely, which I don't think is acceptable / is a decision I'm not comfortable making personally, so instead I opted to split the macro portion of the check into a separate lint so that it can be silenced globally with an attribute if necessary without needing to globally silence the unused_doc_comment lint as well, which is still desireable.

fixes #67838

@rust-highfive
Copy link
Collaborator

r? @ecstatic-morse

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 12, 2020
@Manishearth
Copy link
Member

@bors r+

I was initially concerned that this would break doc comments for macros, but this is just a lint, it's fine. We should not be linting about pretty much anything pre-proc macros except for things which affect lexing, which is true for the other pre-proc-macro pass.

@bors
Copy link
Contributor

bors commented Feb 12, 2020

📌 Commit 03863236992e376a87c6d5efb3961be11721d85a has been approved by Manishearth

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 12, 2020
@yaahc
Copy link
Member Author

yaahc commented Feb 12, 2020

This does break a change made last year to improve diagnostics on macros

tree cabd6022a0ec9a157fdce48be26ddc408d626219
parent 018d4d265fb40ea4301da5dc339bff962a6faa57
author Andy Russell <[email protected]> Thu Jan 24 15:49:03 2019 -0500
committer Andy Russell <[email protected]> Fri Mar 8 12:39:50 2019 -0500

expand unused doc comment diagnostic

Report the diagnostic on macro expansions, and add a label indicating
why the comment is unused.
@@ -802,7 +802,14 @@ impl LintPass for UnusedDocComment {
 }
 
 impl UnusedDocComment {
-    fn warn_if_doc(&self, cx: &EarlyContext, attrs: &[ast::Attribute]) {
+    fn warn_if_doc(
+        &self,
+        cx: &EarlyContext<'_>,
+        node_span: Span,
+        node_kind: &str,
+        is_macro_expansion: bool,
+        attrs: &[ast::Attribute]
+    ) {
         let mut attrs = attrs.into_iter().peekable();
 
         // Accumulate a single span for sugared doc comments.
@@ -825,27 +832,51 @@ impl UnusedDocComment {
             let span = sugared_span.take().unwrap_or_else(|| attr.span);
 
             if attr.name() == "doc" {
-                cx.struct_span_lint(
-                    UNUSED_DOC_COMMENTS,
-                    span,
-                    "doc comment not used by rustdoc",
-                ).emit();
+                let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment");
+
+                err.span_label(
+                    node_span,
+                    format!("rustdoc does not generate documentation for {}", node_kind)
+                );
+
+                if is_macro_expansion {
+                    err.help("to document an item produced by a macro, \
+                              the macro must produce the documentation as part of its expansion");
+                }
+
+                err.emit();
             }
         }
     }
 }

I'd like to not break this if possible, is it possible for a lint to exist in two passes, I really only need the lint on items in fns to be done after expansion so I can strip out doc comments in fn bodies.

@Manishearth
Copy link
Member

@yaahc write two passes instead, one that specifically looks for doc comments on macro expansions only. multiple passes are allowed to produce the same lint

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Feb 12, 2020
@rust-highfive

This comment has been minimized.

@Manishearth
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Feb 12, 2020

📌 Commit a89a791fd3f3665fc9a63f8b837fafe888d35e69 has been approved by Manishearth

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 12, 2020
@yaahc
Copy link
Member Author

yaahc commented Feb 12, 2020

Actually, I think I need to disable the macro prepass lint for check_stmt. I think this will be okay because we probably dont have people commonly trying to declare items in macros as statements and document them at the same time...

@Manishearth
Copy link
Member

@bors r- delegate+

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Feb 12, 2020
@bors
Copy link
Contributor

bors commented Feb 12, 2020

✌️ @yaahc can now approve this pull request

@yaahc
Copy link
Member Author

yaahc commented Feb 12, 2020

So for my needs I would definitely prefer that doc comments on macro calls as statements are still handled in the early_pass so they can be silenced. I tried removing the stmt check in the pre_expansion pass lint with the hope that expr / stmt checks would catch the attributes on the post expansion version but the attributes seem to disappear and we no longer produce a lint on the macro call within the fn body, even if I changed the macro call to actually expand to an expr.

Could I get some help figuring out how to correctly lint for doc comments on macros as expressions from an early pass lint or decide which would be preferable between not linting in this case at all or linting on this but reporting the lint as unused_macro_doc_comment so that it can be silenced independently, either of which would be okay though not ideal solutions for my problem.

@yaahc
Copy link
Member Author

yaahc commented Feb 12, 2020

I went ahead and implemented the version that exports the macro portion of the lint as a separately named lint, in addition to having it implemented as a separate lint pass internally. I figured this would be the most likely solution we'd end up needing.

If someone knows of a way to still appropriately lint on the attributes on macros after they've been expanded then I'm down to put in the work to swap the solution to that, but it looks like prior to this being moved to be a preexpansion pass lint the lint just straight up didn't trigger for macros, so my expectation is that attributes on macros are discarded after expansion, and that this is the only way to preserve the lint but while not requiring a blanket allow on all unused doc comments to silence the macro lint warnings.

@petrochenkov petrochenkov self-assigned this Feb 12, 2020
@Manishearth
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Feb 12, 2020

📌 Commit df6eb29fa0d4003bd0ec2bbf7ef55e4cfb9e5d5c has been approved by Manishearth

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 12, 2020
@rust-highfive

This comment has been minimized.

@petrochenkov
Copy link
Contributor

petrochenkov commented Feb 12, 2020

@bors rollup=never
(I'd like to review this.)

@yaahc
Copy link
Member Author

yaahc commented Feb 22, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Feb 22, 2020

📌 Commit 09bc5e3 has been approved by yaahc

@bors
Copy link
Contributor

bors commented Feb 23, 2020

⌛ Testing commit 09bc5e3 with merge ca07a23...

bors added a commit that referenced this pull request Feb 23, 2020
Split non macro portion of unused_doc_comment from macro part into two passes/lints

## Motivation

This change is motivated by the needs of the [spandoc library](https://github.com/yaahc/spandoc). The specific use case is that my macro is removing doc comments when an attribute is applied to a fn with doc comments, but I would like the lint to still appear when I forget to add the `#[spandoc]` attribute to a fn, so I don't want to have to silence the lint globally.

## Approach

This change splits the `unused _doc_comment` lint into two lints, `unused_macro_doc_comment` and `unused_doc_comment`. The non macro portion is moved into an `early_lint_pass` rather than a pre_expansion_pass. This allows proc macros to silence `unused_doc_comment` warnings by either adding an attribute to silence it or by removing the doc comment before the early_pass runs.

The `unused_macro_doc_comment` lint however will still be impossible for proc-macros to silence, but the only alternative that I can see is to remove this lint entirely, which I don't think is acceptable / is a decision I'm not comfortable making personally, so instead I opted to split the macro portion of the check into a separate lint so that it can be silenced globally with an attribute if necessary without needing to globally silence the `unused_doc_comment` lint as well, which is still desireable.

fixes #67838
@bors
Copy link
Contributor

bors commented Feb 23, 2020

💔 Test failed - checks-azure

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Feb 23, 2020
@petrochenkov
Copy link
Contributor

petrochenkov commented Feb 23, 2020

@yaahc
Meta: the convention is to @bors r=petrochenkov on behalf of the reviewer instead of @bors r+ing on behalf of yourself.

The CI failure looks spurious.
@bors r-

@petrochenkov
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Feb 23, 2020

💡 This pull request was already approved, no need to approve it again.

@bors
Copy link
Contributor

bors commented Feb 23, 2020

📌 Commit 09bc5e3 has been approved by petrochenkov

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 23, 2020
@bors
Copy link
Contributor

bors commented Feb 23, 2020

⌛ Testing commit 09bc5e3 with merge 0cbf1a602ead3e16296c5a43ab78ec5044e309f3...

@rust-highfive
Copy link
Collaborator

Your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@bors
Copy link
Contributor

bors commented Feb 23, 2020

💔 Test failed - checks-azure

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Feb 23, 2020
@petrochenkov
Copy link
Contributor

@bors retry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 23, 2020
@bors
Copy link
Contributor

bors commented Feb 23, 2020

⌛ Testing commit 09bc5e3 with merge b1f395d...

@bors bors mentioned this pull request Feb 23, 2020
@bors
Copy link
Contributor

bors commented Feb 23, 2020

☀️ Test successful - checks-azure
Approved by: petrochenkov
Pushing b1f395d to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Feb 23, 2020
@bors bors merged commit b1f395d into rust-lang:master Feb 23, 2020
@yaahc yaahc deleted the delayed-doc-lint branch February 23, 2020 21:17
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 22, 2020
Clarify unused_doc_comments note on macro invocations

The previous error message used to say:

<pre>
/// doc
^^^^^^^ rustdoc does not generate documentation for <b>macros</b>
</pre>

Obviously we do generate documentation for macros, such as https://docs.rs/bitflags/1.2.1/bitflags/macro.bitflags.html. It's only macro invocations that don't get their own docs. This PR updates the message to say "rustdoc does not generate documentation for <b>macro invocations</b>".

I observe that prior to rust-lang#69084 this used to say "rustdoc does not generate documentation for **macro expansions**", as implemented originally in rust-lang#57882. I don't have a preference between those but I made the commit before looking up the history.

r? @Manishearth
attn: @yaahc @euclio
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move unused_doc_comment lint to a later pass to after proc macro expansion
8 participants